package cn.felord.spring.security.dao;

import cn.felord.spring.security.entity.SysUser;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UsernameNotFoundException;

import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

public class UserDetailsRepository {

    /**
     * 替换为 抽象DAO接口可进行用户持久化操作
     */
    private Map<String, SysUser> users = new HashMap<>();

    /**
     * Create user.
     */
    public void createUser(UserDetails user) {
        SysUser sysUser = new SysUser();
        sysUser.setUsername(user.getUsername());
        sysUser.setEncodePassword(user.getPassword());
        sysUser.setAge(18);
        users.putIfAbsent(user.getUsername(), sysUser);
    }

    /**
     * Update user.
     */
    public void updateUser(UserDetails user) {
        SysUser sysUser = new SysUser();
        sysUser.setUsername(user.getUsername());
        sysUser.setEncodePassword(user.getPassword());
        sysUser.setAge(18);
        users.put(user.getUsername(), sysUser);
    }

    /**
     * Delete user.
     */
    public void deleteUser(String username) {
        users.remove(username);
    }

    public SysUser queryUser(String username) {
        return users.get(username);
    }

    /**
     * Change password.
     */
    public void changePassword(String oldPassword, String newPassword) {
        Authentication currentUser = SecurityContextHolder.getContext().getAuthentication();
        if (currentUser == null) {
            throw new AccessDeniedException("Can't change password as no Authentication object found in context " + "for current user.");
        }

        String username = currentUser.getName();
        SysUser user = users.get(username);
        if (user == null) {
            throw new IllegalStateException("Current user doesn't exist in database.");
        }

        // 实现具体的更新密码逻辑
        if (!Objects.equals(oldPassword, user.getEncodePassword())) {
            throw new IllegalStateException("Current password doesn't  match the password provided");
        }

        SysUser sysUser = new SysUser();
        sysUser.setUsername(user.getUsername());
        sysUser.setEncodePassword(newPassword);
        users.put(username, sysUser);
    }

    /**
     * User exists boolean.
     */
    public boolean userExists(String username) {
        return users.containsKey(username);
    }

    /**
     * Load user by username user details.
     */
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        SysUser sysUser = users.get(username);
        if (sysUser != null) {
            return User.withUsername(username).password(sysUser.getEncodePassword())
                    .authorities(AuthorityUtils.createAuthorityList("ROLE_ADMIN", "ROLE_APP"))
                    .build();
        }
        throw new UsernameNotFoundException("username: " + username + " notfound");
    }
}
